package org.budo.spring.velocity.resource.manager;

import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.resource.Resource;
import org.apache.velocity.runtime.resource.ResourceManagerImpl;
import org.budo.spring.velocity.resource.loader.BudoClasspathResourceLoader;
import org.budo.spring.velocity.view.BudoVelocityConfigurer;
import org.budo.support.slf4j.Slf4j;
import org.budo.support.spring.context.aware.BudoApplicationContextAware;
import org.slf4j.Logger;

/**
 * @author limingwei
 */
public class BudoResourceManager extends ResourceManagerImpl {
    private static final Logger log = Slf4j.getLogger();

    private boolean budoClasspathResourceLoaderAdded = false;

    @Override
    protected Resource loadResource(String resourceName, int resourceType, String encoding) throws ResourceNotFoundException, ParseErrorException {
        this.assertResourceLoader();

        return super.loadResource(resourceName, resourceType, encoding);
    }

    private void assertResourceLoader() {
        if (this.budoClasspathResourceLoaderAdded) {
            return;
        }

        synchronized (BudoResourceManager.class) {
            if (this.budoClasspathResourceLoaderAdded) {
                return;
            }

            this.addBudoResourceLoader();

            this.budoClasspathResourceLoaderAdded = true;
        }
    }

    private void addBudoResourceLoader() {
        for (Object loader : this.resourceLoaders) {
            if (loader instanceof BudoClasspathResourceLoader) {
                log.warn("#61 已存在, loader=" + loader + ", resourceLoaders=" + this.resourceLoaders);
                return;
            }
        }

        BudoClasspathResourceLoader loader = new BudoClasspathResourceLoader();
        loader.setResourceLoaderPath(this.getResourceLoaderPath());

        log.info("#58 addBudoResourceLoader, loader=" + loader);
        this.resourceLoaders.add(loader);
    }

    private String getResourceLoaderPath() {
        BudoVelocityConfigurer configurer = BudoApplicationContextAware.getBean(BudoVelocityConfigurer.class);
        return configurer.getResourceLoaderPath();
    }
}